home *** CD-ROM | disk | FTP | other *** search
- PAGE 255,132
- ; Q
- ; Juline calculates a horozontal row of points for a quadratic
- ; Julia set. The parameters are scaled to be close to the maximum
- ; magnitude for integers and integer arithmetic is used for speed.
- ; The unscaled Julia set is associated with the transformation
- ;
- ; z --> z^2 - L in the region abs(Re(z)) < 2 and abs(Im(z))<1
- ;
- ; To scale to maximum size we use
- ;
- ; x = Re(z) * 2^14 y = Im(z) * 2^15
- ; a = Re(L) * 2^14 b = Im(L) * 2^12
- ;
- ; The transformation can then be written
- ;
- ; x --> [4x^2/2^16 - (2^15 - 1)] - [ y^2/2^16 + (a - 2^15 + 1)]
- ; y --> (8(xy - b*2^16))/2^16
- ;
- ; The intermediate multiplication results are two words long. Each
- ; 2^16 indicates a simple full word shift. The multiplications by
- ; 4 and 8 indicate shifts through both words. The complicated
- ; expressions are chosen so there is no chance of overflow
- ; until the last step. (The term 4x^2/2^16 could be larger than 2^15
- ; but becomes a regular signed integer when (2^15 - 1) is
- ; subtracted. The canceling correction in the second bracketed
- ; expression ensures that it, too, will be a signed integer.)
- ;
- only segment
- assume cs:only, ds:data
-
- picpar struc ; parameter vector in calling program
- xi dw ? ; initial x coord DESTROYED BY JULINE
- yi dw ? ; y coord for line
- delx dw ? ; change in x for one pixel
- a dw ? ; function parameter -- real part (scaled)
- b dw ? ; imag part (scaled)
- maxit dw ? ; maximum function iterations for a pixel
- c1 dw ? ;if iterations LEFT < c1 use color 1
- c2 dw ? ;if iterations LEFT < c2 use color 2 (<c1)
- nbyte dw ? ; DESTROYED BY JULINE number of bytes to output
- picpar ends
-
- bigint equ 7FFFH ; 2^15 - 1
-
- juline proc far ; param are offsets of output and struct picpar
-
- ; REGISTER USAGE FOR MAIN LOOP SCREEN CALC
- ; ax arith partial screen byte
- ; bx y param offset then output offset
- ; cx count of iterations
- ; dx high mult
- ; bp x point to param pointer
- ; si a - bigint
- ; di b
-
- jul: push bp ; must be saved
- mov bp,sp
- add bp,6 ; points to offset of picpar,
- ; bp + 2 points to output offset
- mov bx,[bp] ;offset of picpar
- mov si, [bx].a ; keep a in si for whole routine
- sub si,bigint ; shifted by bigint
- mov di, [bx].b ; keep b for whole routine
- mov ax, [bx].delx ;set xi
- sub [bx].xi, ax ; back as initialization
-
- byteout: ; loop for output byte
-
- ; init for pixel loop
- mov cx, 3
- push cx ;count of shifts to do
- xor cx, cx
- push cx
-
- pixel: ; first initialize for iteration
- push bp ; about to be destroyed for iteration
- mov cx, [bx].maxit ; number of iterations
- mov bp, [bx].delx
- add bp, [bx].xi ;increment starting x
- mov [bx].xi, bp ;save new one
- mov bx, [bx].yi ; starting y
-
- iterate: ; iterate the quadratic function
- mov ax, bp
- imul ax ; square ax -- high word to dx
- rcl ax, 1 ; start first of two left shifts
- rcl dx, 1
- rcl ax, 1 ; low bits in ax do not matter
- rcl dx, 1
- sub dx, bigint ;overflow prevention
- xchg dx, bp ;save first term of new x and get old x
- mov ax, bx ; prepare to mult by y
- imul dx ; mult dx and ax (x and y)
- sub dx, di ; subtract imaginary part of parameter
- cmp dx, 0FFFH ; see if following three shifts
- jg enditer ; will cause positive overflow,
- cmp dx, 0F000H ; or
- jl enditer ;negative overflow
- ; otherwise can shift
- rcl ax, 1 ; start first of three shifts
- rcl dx, 1
- rcl ax, 1
- rcl dx, 1
- rcl ax, 1
- rcl dx, 1 ; have new y
- mov ax, bx ; get old y
- mov bx, dx ; and replace by new one
- imul ax ; square old y -- starting on 2nd term of new x
- add dx, si ; include real part of parameter
- sub bp, dx ; now have new x
- jo enditer
- loop iterate
-
- enditer:
- pop bp
- pop ax ; screen word
- mov bx, [bp]
- cmp cx, [bx].c1
- jg havecolor ; backround color
- inc ax
- cmp cx, [bx].c2
- jg havecolor ; color 1
- inc ax
- cmp cx, 0
- jg havecolor ; color 2
- inc ax ; color 3
- havecolor:
- pop cx ; shift count, replace iter count
- jcxz bytedone
- dec cx
- push cx
- sal ax, 1 ; ready for two new bits
- sal ax, 1
- push ax ; save intermediate screen word
- jmp pixel
- bytedone:
- mov bx,[bp] + 2 ; get output address
- mov [bx], al ; save screen byte
- inc bx ; advance
- mov [bp] +2, bx ; output address
- mov bx, [bp] ; replace picpar offset
- dec [bx].nbyte ; update number of words to generate
- jz cleanup
- jmp byteout
-
- cleanup:
- pop bp ; restore original base
- ret 4
- juline endp
-
-
- ; The driver for juline needs to set up the parameter struct and
- ; provide space for the output
-
- data segment
- param picpar <0a000h, 1 shl 14, 3 shl 10, 0 shl 14, 0 shl 12,7,5,3,4>
- scrstr db 1160 dup(?)
- data ends
-
- ;picpar struc ; parameter vector in calling program
- ; xi dw -3 shl 13 ; initial x coord DESTROYED BY JULINE
- ; yi dw 0 shl 15 ; y coord for line
- ; delx dw 3 shl 9 ; change in x for one pixel
- ; a dw 0 shl 14 ; function parameter -- real part (scaled)
- ; b dw 0 shl 12 ; imag part (scaled)
- ; maxit dw 7 ; maximum function iterations for a pixel
- ; c1 dw 5 ;if iterations LEFT < c1 use color 1
- ; c2 dw 3 ;if iterations LEFT < c2 use color 2 (<c1)
- ; nbyte dw 4 ; DESTROYED BY JULINE number of bytes to output
- ;picpar ends
-
- driver: ; PUSH PARAMETER ADDRESSES
- mov ax, seg data
- mov ds, ax
- mov ax, offset scrstr
- push ax
- mov ax, offset param
- push ax
- call far ptr jul
-
-
- only ends
-
- stack segment stack
- assume ss:stack
- dw 64 dup (?)
- stack ends
-
- public cleanup, driver, enditer, havecolor, iterate, jul
- public juline, param, pixel, scrstr, bytedone, byteout
- end driver